﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConditionJudge.Question;

namespace ConditionJudge.Answer
{
    class Edward : IConditionJudge
    {
        public string Judgement(string expression, int x)
        {
            List<exp> exps = makeexps(expression, x);
            try
            {
                if (getexpresult(exps) == true)
                {
                    return "TT";
                }
                else
                {
                    return "TF";
                }
            }
            catch (Exception)
            {
                return "FF";
            }

        }

        private bool getexpresult(List<exp> exps)
        {
            bool? currentresult = null;
            for (int i = 0; i < exps.Count; i++)
            {
                if (exps[i].op != "(" || exps[i].op != ")")
                {
                    //is exp
                    if (currentresult != null)
                    {
                        currentresult = (bool)currentresult && exps[i].do_op();
                    }
                    else
                    {
                        currentresult = exps[i].do_op();
                    }
                }
                else
                {
                    //is bracket
                    List<exp> tempexps = new List<exp>();
                    int tempi = ++i;
                    while (true)
                    {
                        if (exps[i].op == ")")
                        {
                            break;
                        }
                        tempexps.Add(exps[i]);
                        ++i;
                    }
                    currentresult = (bool)currentresult && getexpresult(tempexps);
                    i = tempi - 1;
                }
            }
            return true;
        }

        private List<exp> makeexps(string expression, int x)
        {
            List<exp> list = new List<exp>();

            int? tempop1 = null;
            int? tempop2 = null;
            string tempop = null;
            for (int i = 0; i < expression.Length; i++)
            {
                //igone ' '
                if (expression[i] != ' ')
                {
                    #region switch
                    switch (expression[i])
                    {
                        case 'X':
                            tempop1 = x;
                            break;
                        case '>':
                            //if >= else >
                            if (expression[i + 1] == '=')
                            {
                                tempop = ">=";
                                ++i;//skip next char
                            }
                            else
                            {
                                tempop = ">";
                            }
                            break;
                        case '<':
                            //if <= else <
                            if (expression[i + 1] == '=')
                            {
                                tempop = "<=";
                                ++i;//skip next char
                            }
                            else
                            {
                                tempop = "<";
                            }
                            break;
                        case '=':
                            tempop = "==";
                            ++i;//skip next char
                            break;
                        case '!':
                            //!=         
                            tempop = "!=";
                            ++i;//skip next char
                            break;
                        case '&':
                            //&&
                            tempop = "&&";
                            ++i;//skip next char
                            break;
                        case '|':
                            //||
                            tempop = "||";
                            ++i;//skip next char
                            break;
                        case '(':
                            tempop = "(";
                            break;
                        case ')':
                            tempop = ")";
                            break;
                        default:
                            //if op is number
                            if (expression[i] >= '0' && expression[i] <= '9')
                            {
                                try
                                {
                                    tempop2 = Convert.ToInt32(expression[i]);
                                }
                                catch (Exception)
                                {

                                    throw;
                                }
                            }
                            break;
                    }
                    #endregion switch
                }
                if (tempop1 != null && tempop2 != null && tempop != null)
                {
                    list.Add(new exp((int)tempop1, (int)tempop2, tempop));
                }
                else if (tempop == "(" || tempop == ")")
                {
                    list.Add(new exp(tempop));
                }
            }
            return list;
        }
    }
    class exp
    {
        public int op1;
        public int op2;
        public string op;
        public exp(int op1, int op2, string op)
        {
            this.op1 = op1;
            this.op2 = op2;
            this.op = op;
        }

        public exp(string op)
        {
            this.op = op;
        }

        public bool do_op()
        {
            switch (op)
            {
                case ">":
                    return op1 > op2;
                    break;
                case "<":
                    return op1 < op2;
                    break;
                case ">=":
                    return op1 >= op2;
                    break;
                case "<=":
                    return op1 <= op2;
                    break;
                case "==":
                    return op1 == op2;
                    break;
                case "!=":
                    return op1 != op2;
                    break;
                default:
                    break;
            }
            throw new Exception();
        }
    }

}
